package com.admin.common.biz;

import org.apache.commons.crypto.cipher.CryptoCipher;
import org.apache.commons.crypto.cipher.CryptoCipherFactory;
import org.apache.commons.crypto.utils.Utils;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Base64;
import java.util.Properties;

/**
 * 官网例子
 * 需增加Base64编码，toString() 乱码不可逆
 */
public class EncryptionDecryption {
    private static final String KEY_VAL = "1234567890123456";
    private static final String IV_VAL = "1234567890123456";
    private static final String transform = "AES/CBC/PKCS5Padding";

    private static final SecretKeySpec key = new SecretKeySpec(getUTF8Bytes(KEY_VAL), "AES");
    private static final IvParameterSpec iv = new IvParameterSpec(getUTF8Bytes(IV_VAL));

    private static Properties properties = new Properties();

    public static String encryption(String str) throws Exception {
        properties.setProperty(CryptoCipherFactory.CLASSES_KEY, CryptoCipherFactory.CipherProvider.OPENSSL.getClassName());
        CryptoCipher encipher = Utils.getCipherInstance(transform, properties);
        byte[] input = getUTF8Bytes(str);
        byte[] output = new byte[32];

        //Initializes the cipher with ENCRYPT_MODE, key and iv.
        encipher.init(Cipher.ENCRYPT_MODE, key, iv);
        //Continues a multiple-part encryption/decryption operation for byte array.
        int updateBytes = encipher.update(input, 0, input.length, output, 0);
        int finalBytes = encipher.doFinal(input, 0, 0, output, updateBytes);
        encipher.close();
        String result = new String(Base64.getEncoder().encode(Arrays.copyOf(output, updateBytes + finalBytes)));

//        System.out.println(Arrays.toString(Arrays.copyOf(output, updateBytes+finalBytes)));
        return result;
    }

    public static String decryption(String str) throws Exception {
//        byte[] output = new byte[32];
        properties.setProperty(CryptoCipherFactory.CLASSES_KEY, CryptoCipherFactory.CipherProvider.JCE.getClassName());
        CryptoCipher decipher = Utils.getCipherInstance(transform, properties);
        decipher.init(Cipher.DECRYPT_MODE, key, iv);

        byte[] input = Base64.getDecoder().decode(str);
        byte[] decoded = new byte[32];
        decipher.doFinal(input, 0, input.length, decoded, 0);
        return new String(decoded, StandardCharsets.UTF_8);
    }

    private static byte[] getUTF8Bytes(String input) {
        return input.getBytes(StandardCharsets.UTF_8);
    }

    public static void main(String[] arges) throws Exception {
        String jack = "jack_test_22221";
        String pwd = encryption(jack);
        System.out.println(pwd);
        System.out.println(decryption(pwd));
    }
}
